/**
*  
* @Function 批量核查详情服务 
* @ProjectName credit-data-platform 
* @PackageName com.py.credit.service.impl    
* @FileName BatchReportDetailServiceImpl.java    
* @Date 2018年10月19日下午4:30:15
* @Author Min DongXv
* @Copyright (c) 2018, 金电联行 All Rights Reserved.   
*   
*/
package com.py.credit.service.impl;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletResponse;

import cn.hutool.json.JSON;
import com.alibaba.fastjson.JSONObject;
import com.py.credit.entity.Hcbg;
import com.py.credit.entity.TableResult;
import com.py.credit.service.CreditReportService;
import com.py.credit.service.SSearchService;
import com.py.credit.service.ScontentService;
import com.py.credit.utils.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import com.py.credit.common.rest.RestServiceResult;
import com.py.credit.dao.BatchReportDetailDao;
import com.py.credit.entity.BatchReportDetailEntity;
import com.py.credit.entity.ZipEntity;
import com.py.credit.service.BatchReportDetailService;
import com.py.framework.core.common.Page;

/**
 * 
 * @Function 批量核查详情服务
 * @ClassName BatchReportDetailServiceImpl
 * @Date 2018年10月19日 下午4:30:15
 * @Author Min DongXv
 * 
 */
@Service
public class BatchReportDetailServiceImpl implements BatchReportDetailService {

	private static final int REPORT_STATUS_SUCCESS = 3;

	@Autowired
	private BatchReportDetailDao batchReportDetailDao;

	@Autowired
	private CreditReportService creditReportService;

	@Autowired
	private ScontentService sContentService;

	@Autowired
	private SSearchService sSearchService;

	@Autowired
	private BgdzServiceImpl bgdzService;

	/**
	 *
	 * @Function 分页查询批量核查详情
	 * @FileName BatchReportDetailServiceImpl.java
	 * @MethodName getBatchReportDetailByConditionForPage
	 * @param columns
	 * @param additionalColumns
	 * @param condition
	 * @param page
	 * @return
	 * @Date 2018年10月19日 下午4:30:22
	 * @Author Min DongXv
	 *
	 */
	@Override
	public List<Map<String, Object>> getBatchReportDetailByConditionForPage(List<String> columns,
			String[] additionalColumns, String condition, Page page, String batchId) {
		List<String> conditions = SQLBuilder.createConditionSql(condition);
		return batchReportDetailDao.getBatchReportDetailByConditionForPage(columns, additionalColumns, conditions, page,
				batchId);
	}

	/**
	 *
	 * @Function 批量新增核查信息
	 * @FileName BatchReportDetailServiceImpl.java
	 * @MethodName batchAddDetails
	 * @param list
	 * @Date 2018年10月19日 下午4:30:22
	 * @Author Min DongXv
	 *
	 */
	@Override
	public void batchAddDetails(List<BatchReportDetailEntity> list) {
		batchReportDetailDao.batchAddDetails(list);
	}

	/**
	 *
	 * @Function 更新导入信息的基本信息
	 * @FileName BatchReportDetailServiceImpl.java
	 * @MethodName updateDetailInfo
	 * @param batchId
	 * @Date 2018年10月19日 下午4:30:22
	 * @Author Min DongXv
	 *
	 */
	@Override
	public void updateDetailInfo(String batchId) {
		batchReportDetailDao.updateDetailInfo(batchId);
	}

	/**
	 *
	 * @Function 获取待生成的核查信息
	 * @FileName BatchReportDetailServiceImpl.java
	 * @MethodName getWaitCreateDetail
	 * @param batchId
	 * @Date 2018年10月19日 下午4:30:22
	 * @Author Min DongXv
	 *
	 */
	@Override
	public List<BatchReportDetailEntity> getWaitCreateDetail(String batchId) {
		return batchReportDetailDao.getWaitCreateDetail(batchId);
	}

	/**
	 *
	 * @Function 获取待生成的核查信息数量
	 * @FileName BatchReportDetailServiceImpl.java
	 * @MethodName getWaitCreateDetailCount
	 * @param batchId
	 * @return
	 * @Date 2018年10月22日 下午6:03:18
	 * @Author Min DongXv
	 *
	 */
	@Override
	public int getWaitCreateDetailCount(String batchId) {
		return batchReportDetailDao.getWaitCreateDetailCount(batchId);
	}

	/**
	 * 
	 * @Function 更新报告状态
	 * @FileName BatchReportDetailServiceImpl.java
	 * @MethodName updateDetailStatus
	 * @param id
	 *            编号
	 * @param reportStatus
	 *            报告状态
	 * @param orgReportStatus
	 *            报告原始状态
	 * @Date 2018年10月19日 下午4:38:55
	 * @Author Min DongXv
	 *
	 */
	@Override
	public void updateDetailStatus(Integer id, int reportStatus, int orgReportStatus) {
		Map<String, Object> map = new HashMap<>(3);
		map.put("id", id);
		map.put("reportStatus", reportStatus);
		map.put("orgReportStatus", orgReportStatus);
		batchReportDetailDao.updateDetailStatus(map);
	}

	/**
	 *
	 * @Function 获取报告详情
	 * @FileName BatchReportDetailServiceImpl.java
	 * @MethodName getBatchDetailById
	 * @param id
	 * @Date 2018年10月22日 上午10:14:38
	 * @Author Min DongXv
	 *
	 */
	@Override
	public BatchReportDetailEntity getBatchDetailById(Integer id) {
		return batchReportDetailDao.getBatchDetailById(id, REPORT_STATUS_SUCCESS);
	}

	/**
	 * 
	 * @Function 报告下载
	 * @FileName BatchReportDetailServiceImpl.java
	 * @MethodName download
	 * @param absolutepath
	 *            文件存放地址
	 * @param id
	 *            报告编号
	 * @param response
	 * @return
	 * @Date 2018年10月22日 上午10:29:11
	 * @Author Min DongXv
	 *
	 */
	@Override
	public RestServiceResult<Object> download(String absolutepath, Integer id, HttpServletResponse response) {
		RestServiceResult<Object> result = new RestServiceResult<>();
		BatchReportDetailEntity entity = batchReportDetailDao.getBatchDetailById(id, REPORT_STATUS_SUCCESS);
		if (null != entity) {
			String filePatch = filePatch(absolutepath, entity.getBatchId());
			String fileName = entity.getReportName();
			if (!new File(filePatch + fileName).exists()) {
				result.setCode(RestServiceResult.CODE_UNKNOW);
				result.setMsg("报告已不存在,请重新生成");
				return result;
			}
			return HtmlToPdfUtils.download(filePatch, fileName, response);
		} else {
			result.setCode(RestServiceResult.CODE_UNKNOW);
			result.setMsg("文件未生成");
			return result;
		}
	}

	/**
	 * 
	 * @Function 报告预览
	 * @FileName BatchReportDetailServiceImpl.java
	 * @MethodName preview
	 * @param absolutepath
	 *            文件存放地址
	 * @param id
	 *            报告编号
	 * @param response
	 * @return
	 * @Date 2018年10月22日 上午11:18:18
	 * @Author Min DongXv
	 *
	 */
	@Override
	public RestServiceResult<Object> preview(String absolutepath, Integer id, HttpServletResponse response) {
		RestServiceResult<Object> result = new RestServiceResult<>();
		BatchReportDetailEntity entity = batchReportDetailDao.getBatchDetailById(id, REPORT_STATUS_SUCCESS);
		if (null != entity) {
			String filePatch = filePatch(absolutepath, entity.getBatchId());
			return HtmlToPdfUtils.preview(filePatch, entity.getReportName(), response);
		} else {
			result.setCode(RestServiceResult.CODE_UNKNOW);
			result.setMsg("文件未生成");
			return result;
		}
	}

	/**
	 *
	 * @Function 批量更新待生成记录为生成中
	 * @FileName BatchReportDetailServiceImpl.java
	 * @MethodName batchUpdateStatus
	 * @Date 2018年10月23日 上午10:41:56
	 * @Author Min DongXv
	 *
	 */
	@Override
	public void batchUpdateStatus() {
		batchReportDetailDao.batchUpdateStatus();
	}

	/**
	 *
	 * @Function 获取生成中报告数量,一小时之前还是生成中的详情不计入数量，可以进行重新生成
	 * @FileName BatchReportDetailServiceImpl.java
	 * @MethodName getCreatingNum
	 * @return
	 * @Date 2018年10月23日 上午10:42:42
	 * @Author Min DongXv
	 *
	 */
	@Override
	public int getCreatingNum() {
		return batchReportDetailDao.getCreatingNum();
	}

	/**
	 * 
	 * @Function 获取已生成报告的文件名
	 * @FileName BatchReportDetailServiceImpl.java
	 * @MethodName getReportName
	 * @param batchId
	 *            批次ID
	 * @return
	 * @Date 2018年10月23日 下午3:51:18
	 * @Author Min DongXv
	 *
	 */
	@Override
	public List<String> getReportName(String batchId) {
		return batchReportDetailDao.getReportName(batchId);
	}

	/**
	 *
	 * @Function 选择性下载批量核查报告
	 * @FileName BatchReportDetailServiceImpl.java
	 * @MethodName getReports
	 * @param absolutepath
	 *            文件存放地址
	 * @param batchId
	 *            批次ID
	 * @param list
	 *            选择ID列表
	 * @param response
	 * @param zipName
	 *            压缩包名称
	 * @return
	 * @Date 2018年10月23日 下午6:29:46
	 * @Author Min DongXv
	 *
	 */
	@Override
	public RestServiceResult<Object> getReports(String zipPath, HttpServletResponse response, String zipName) {
		return ZipUtil.zipDownload(zipName, response, zipPath);
	}

	/**
	 * 
	 * @Function 校验下载文件
	 * @FileName BatchReportDetailServiceImpl.java
	 * @MethodName checkReports
	 * @param absolutepath
	 * @param batchId
	 * @param list
	 * @return
	 * @Date 2018年10月25日 下午5:57:51
	 * @Author Min DongXv
	 *
	 */
	@Override
	public RestServiceResult<String> checkReports(String absolutepath, String batchId, String[] list) {
		RestServiceResult<String> result = new RestServiceResult<>();
		if (null != list) {
			List<Integer> ids = new ArrayList<>(list.length);
			for (String s : list) {
				ids.add(Integer.parseInt(s));
			}
			List<String> fileNames = batchReportDetailDao.getReportNameById(ids);
			if (!CollectionUtils.isEmpty(fileNames)) {
				String path = filePatch(absolutepath, batchId);
				// 有多个文件，下载zip
				List<ZipEntity> filePaths = new ArrayList<>(fileNames.size());
				for (String name : fileNames) {
					ZipEntity ze = new ZipEntity(name, path);
					filePaths.add(ze);
				}
				return ZipUtil.zip(filePaths);
			} else {
				result.setCode(RestServiceResult.CODE_UNKNOW);
				result.setMsg("没有可供下载的报告");
			}
		} else {
			result.setCode(RestServiceResult.CODE_UNKNOW);
			result.setMsg("没有可供下载的报告");
		}
		return result;
	}

	/**
	 *
	 * @Function 报告重新生成
	 * @FileName BatchReportDetailServiceImpl.java
	 * @MethodName reCreateReport
	 * @param absolutepath
	 *            文件存放路径
	 * @param pdfJsPath
	 *            pdf生成脚本存放地址
	 * @param pdfPagePath
	 *            pdf页面路径
	 * @param googlePath
	 *            谷歌浏览器地址
	 * @param kId
	 *            库ID，默认100000
	 * @param id
	 *            报告详情地址
	 * @return
	 * @Date 2018年10月25日 上午9:56:26
	 * @Author Min DongXv
	 *
	 */
	@Transactional(rollbackFor = Exception.class)
	@Override
	public RestServiceResult<Object> reCreateReport(String absolutepath, String pdfJsPath, String pdfPagePath,
			String googlePath, String kId, Integer id) {
		RestServiceResult<Object> result = new RestServiceResult<>();
		// 根据ID获取批次详情
		BatchReportDetailEntity entity = batchReportDetailDao.getBatchDetailById(id, 0);
		if (null != entity) {
			// 初始状态
			Integer orgStatus = entity.getReportStatus();
			// 对于无匹配企业的数据先进行关联匹配操作，关联完还是匹配不上的直接返回
			if (StringUtils.isBlank(entity.getTybm())) {
				batchReportDetailDao.updateDetailInfoById(entity.getId());
				entity = batchReportDetailDao.getBatchDetailById(id, 2);
				if (null == entity || StringUtils.isBlank(entity.getTybm())) {
					result.setCode(RestServiceResult.CODE_UNKNOW);
					result.setMsg("该企业未找到匹配的数据");
					return result;
				}
			}
			// 只有无匹配企业、生成成功和生成失败的可以重新生成
			if (1 == orgStatus || 3 == orgStatus || 4 == orgStatus) {
				String filePath = filePatch(absolutepath, entity.getBatchId());
				/*boolean data = true;HtmlToPdfUtils.googleConventSync(pdfJsPath,
						pdfPagePath + "/tybm=" + entity.getTybm() + "/kId=" + kId + "/keyword=" + entity.getA000001(),
						filePath, entity.getReportName(), null, true, googlePath);*/
				Map<String, Object> templateData = this.getTemplateData(entity.getTybm(), kId);
				templateData.put("firstTitle", entity.getA000001());
				boolean data = FreeeMarkerUtils.html2Pdf(templateData, "/template/pdf_template_freemarker.html", filePath, entity.getReportName(), absolutepath);


				// 初始状态为3 生成成功
				Integer status = 3;
				// 生成异常，报告状态为4
				if (!data) {
					result.setCode(RestServiceResult.CODE_UNKNOW);
					result.setMsg("报告生成异常");
					status = 4;
				}
				updateDetailStatus(id, status, entity.getReportStatus());
				// 压缩包更新
				ZipUtil.zipUpdateByAnt(filePath, "批量核查", filePath + File.separator + entity.getReportName());
			}
		} else {
			result.setCode(RestServiceResult.CODE_UNKNOW);
			result.setMsg("报告生成中");
		}
		return result;
	}

	/**
	 * 
	 * @Function 文件是否存在
	 * @FileName BatchReportDetailServiceImpl.java
	 * @MethodName fileExist
	 * @param absolutepath
	 * @param id
	 * @return
	 * @Date 2018年10月25日 上午10:52:56
	 * @Author Min DongXv
	 *
	 */
	@Override
	public RestServiceResult<Object> fileExist(String absolutepath, Integer id) {
		RestServiceResult<Object> result = new RestServiceResult<>();
		BatchReportDetailEntity entity = batchReportDetailDao.getBatchDetailById(id, REPORT_STATUS_SUCCESS);
		if (null != entity) {
			String filePatch = filePatch(absolutepath, entity.getBatchId());
			return HtmlToPdfUtils.fileExist(filePatch, entity.getReportName());
		} else {
			result.setCode(RestServiceResult.CODE_UNKNOW);
			result.setMsg("文件未生成");
			return result;
		}
	}

	/**
	 * 
	 * @Function 批量下载的文件是否存在
	 * @FileName BatchReportDetailServiceImpl.java
	 * @MethodName filesExist
	 * @param absolutepath
	 *            文件是否存在
	 * @param batchId
	 *            批次信息
	 * @param list
	 *            ID集合
	 * @return
	 * @Date 2018年10月25日 上午11:01:03
	 * @Author Min DongXv
	 *
	 */
	@Override
	public RestServiceResult<Object> filesExist(String absolutepath, String batchId, String[] list) {
		RestServiceResult<Object> result = new RestServiceResult<>();
		if (null != list) {
			List<Integer> ids = new ArrayList<>(list.length);
			for (String s : list) {
				ids.add(Integer.parseInt(s));
			}
			List<String> fileNames = batchReportDetailDao.getReportNameById(ids);
			if (!CollectionUtils.isEmpty(fileNames)) {
				String path = filePatch(absolutepath, batchId);
				// 只有一个文件
				if (fileNames.size() == 1) {
					return HtmlToPdfUtils.fileExist(path, fileNames.get(0));
				}
			} else {
				result.setCode(RestServiceResult.CODE_UNKNOW);
				result.setMsg("没有可供下载的报告");
			}
		} else {
			result.setCode(RestServiceResult.CODE_UNKNOW);
			result.setMsg("没有可供下载的报告");
		}
		return result;
	}

	/**
	 * 
	 * @Function 获取报告路径
	 * @FileName BatchReportDetailServiceImpl.java
	 * @MethodName filePatch
	 * @param absolutepath
	 *            文件存放地址
	 * @param batchId
	 *            批次信息
	 * @return
	 * @Date 2018年10月22日 上午10:29:11
	 * @Author Min DongXv
	 *
	 */
	private String filePatch(String absolutepath, String batchId) {
		return absolutepath + File.separator + "batchReport" + File.separator + batchId + File.separator;
	}

	/**
	 * 获取生成PDF需要的数据
	 * @param tybm
	 * @param kId
	 * @return
	 */
	private Map<String, Object> getTemplateData(String tybm, String kId) {
		Map<String, Object> result = new HashMap<String, Object>();

		String number = creditReportService.getReportSerials(kId, DateUtils.getCurrentTime());
		Map<String, Object> detail = sContentService.getDetail(kId, tybm, "XYHC", null);
		Map<String, List<TableResult>> map = new HashMap<String, List<TableResult>>();
		List<TableResult> assembleTableComponent = sSearchService.assembleTableComponent((List<TableResult>) detail.get("results"));

		StringBuilder catalogList = new StringBuilder();
		StringBuilder tableList = new StringBuilder();
		for (TableResult tableResult : assembleTableComponent) {
			String categoryCode = tableResult.getCategoryCode();
			if (map.containsKey(categoryCode)) {
				List<TableResult> list = map.get(categoryCode);
				list.add(tableResult);
			} else {
				List<TableResult> rs = new ArrayList<TableResult>();
				rs.add(tableResult);
				map.put(categoryCode, rs);
			}
		}

		int index = 0;
		for(String key : map.keySet()) {
			index ++;
			List<TableResult> trList = map.get(key);
			for(int i =0; i<trList.size(); i++) {
				TableResult tableResult = trList.get(i);
				if (i == 0) {
					catalogList.append("<div>").append(index).append(tableResult.getCategoryName()).append("</div><p>");
					tableList.append("<h3><span>").append(tableResult.getCategoryName()).append("</span></h3>");
				}
				tableList.append("<div class=\"tableL\"><h4>").append(tableResult.getTableNameCN()).append("</h4>").append(tableResult.getTableComponent()).append("</div>");
				if (i == trList.size()-1) {
					catalogList.append("<span>").append(tableResult.getTableNameCN()).append("</span>");
				} else {

					catalogList.append("<span>").append(tableResult.getTableNameCN()).append("、</span>");
				}
			}
			catalogList.append("</p>");

		}

		Hcbg latest = bgdzService.getLatest();
		latest.setReportNo(latest.getReportNo() + DateUtils.getStringOfTodayDate(DateUtils.SIMPLE_PATTERN) + number);
		result.put("firstReportNum", latest.getReportNo());
		result.put("reportProducer", latest.getReportProducer());
		result.put("reportDate", DateUtils.getStringOfTodayDate("yyyy年MM月dd日"));
		result.put("reportStatment", latest.getReportStatment());

		result.put("catalogList", catalogList.toString());
		result.put("tableList", tableList.toString());
		if (StringUtils.isNotBlank(latest.getWatermarker())) {
			result.put("waterPath", latest.getWatermarker().substring(0, latest.getWatermarker().lastIndexOf("/") + 1));
			result.put("water", latest.getWatermarker().substring(latest.getWatermarker().lastIndexOf("/") + 1));
		}
		return result;
	}
}
